﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.CodeDom;
using System.Data.Common;
using System.CodeDom.Compiler;

namespace OrmAuto
{
		public class ClassCreator
		{
				//1° faccio la classe
				public object getClassedinamica(DbDataReader reader,string nameSpace, string nomeClasse)
				{
						var unitCode = createClasse(nameSpace, nomeClasse, reader);
						var cr=  compileClass(unitCode);
						object o = cr.CompiledAssembly.CreateInstance(nameSpace + "." + nomeClasse);
				  return o;
						
				}//fM



				private static CodeCompileUnit createClasse(string nameSpace, string nomeClasse, DbDataReader pDr)
				{
						CodeCompileUnit compunit = new CodeCompileUnit();
						CodeNamespace TheName = new CodeNamespace(nameSpace);
						compunit.Namespaces.Add(TheName);
						TheName.Imports.Add(new CodeNamespaceImport("System"));
						CodeTypeDeclaration Class1 = new CodeTypeDeclaration(nomeClasse);
						TheName.Types.Add(Class1);

						CodeMemberProperty prop = null;
						for (int i = 0; i < pDr.VisibleFieldCount; i++)
						{
								prop = new CodeMemberProperty () ;
								prop.Attributes = MemberAttributes.Public;
								prop.HasGet = true;
								prop.HasSet = true;
								prop.Name = pDr.GetName(i);
								prop.Type.BaseType = pDr.GetFieldType(i).ToString();

								Class1.Members.Add(prop);

						}

						return  compunit;
				}//fM


				private CompilerResults compileClass(CodeCompileUnit compUnit)
				{
						CompilerParameters compparams = new CompilerParameters(new string[] { "mscorlib.dll" });
						compparams.GenerateInMemory = true;
						//uncomment following if you like to write dll to disk
						//compparams.OutputAssembly=" HelloWorld.dll";
						Microsoft.CSharp.CSharpCodeProvider csharp = new Microsoft.CSharp.CSharpCodeProvider();
						ICodeCompiler cscompiler = csharp.CreateCompiler();
						CompilerResults compresult = cscompiler.CompileAssemblyFromDom(compparams, compUnit);
						if (compresult == null || compresult.Errors.Count > 0)
								return null;

						return compresult ;
				}//fM


				public void testClasseGenerata(CompilerResults compresult, string nameSpace, string nomeClasse, string methodToTest, object[] parametri)
				{
						object o = compresult.CompiledAssembly.CreateInstance(nameSpace + "." + nomeClasse);
						Type test = compresult.CompiledAssembly.GetType(nameSpace + "." + nomeClasse);

						MethodInfo m = test.GetMethod(methodToTest);
						object[] arg = new object[1];
						arg[0] = parametri[0];// " Hello World!";
						m.Invoke(o, arg);

				}//fM

		}//fM
}
